

class Vertex{
public:
    float x,y,z;//pos in world space
    float csx,csy,csz;//pos in camara space
    float scx,scy,scz;//pos in screen space
    bool inSc;//In the screen 
    Vertex():Vertex(0.0,0.0,0.0){};
    Vertex(float _x,float _y,float _z):
        x(_x),y(_y),z(_z),
        scx(0),scy(0),scz(0),
        csx(0),csy(0),csz(0),
        inSc(false)
    {};
    void merge(float _x,float _y,float _z){x=_x;y=_y;z=_z;}
    bool drawable(){return inSc;};
    void draw(SDL_Renderer* renderer){if(drawable()){SDL_RenderDrawPoint(renderer,scx,scy);}}
    void WorldToCamara(Camara camara){
        float temx,temy,temz;
        temx=x-camara.x;
        temy=y-camara.y;
        temz=z-camara.z;
        temy=-temy;
        float a,b;
        //y -a
        a=cos(-camara.alpha*pi/180)*temz-sin(-camara.alpha*pi/180)*temx;
        b=sin(-camara.alpha*pi/180)*temz+cos(-camara.alpha*pi/180)*temx;
        temz=a;
        temx=b;
        //x -b
        a=cos(-camara.beta*pi/180)*temy-sin(-camara.beta*pi/180)*temz;
        b=sin(-camara.beta*pi/180)*temy+cos(-camara.beta*pi/180)*temz;
        temy=a;
        temz=b;
        //z -g
        a=cos(camara.gamma*pi/180)*temx-sin(camara.gamma*pi/180)*temy;
        b=sin(camara.gamma*pi/180)*temx+cos(camara.gamma*pi/180)*temy;
        temx=a;
        temy=b;
        csx=temx,csy=temy;csz=temz;
        CamaraToScreen(camara);
        ifInScreenSpace(camara);
    }
    void CamaraToWorld(Camara camara){

        if(ifInScreenSpace(camara)){
            ScreenToCamara(camara);
        };
        float temx=csx;
        float temy=csy;
        float temz=csz;
        float a,b;
        //z -g
        a=cos(-camara.gamma*pi/180)*temx-sin(-camara.gamma*pi/180)*temy;
        b=sin(-camara.gamma*pi/180)*temx+cos(-camara.gamma*pi/180)*temy;
        temx=a;
        temy=b;
        //x -b
        a=cos(+camara.beta *pi/180)*temy-sin(+camara.beta *pi/180)*temz;
        b=sin(+camara.beta *pi/180)*temy+cos(+camara.beta *pi/180)*temz;
        temy=a;
        temz=b;
        //y -a
        a=cos(+camara.alpha*pi/180)*temz-sin(+camara.alpha*pi/180)*temx;
        b=sin(+camara.alpha*pi/180)*temz+cos(+camara.alpha*pi/180)*temx;
        temz=a;
        temx=b;
        
        temy=-temy;

        x=temx+camara.x;
        y=temy+camara.y;
        z=temz+camara.z;

    }
    void CamaraToScreen(Camara camara){
        // if(csz<camara.n||csz>camara.f)return;
        float temx=csx,temy=csy,temz=csz;
        if (temz>0){
            temx*=camara.d/temz;temx/=camara.r;
            temy*=camara.d/temz;temy/=camara.t;
            temx*=SCREEN_W/2.0;temx+=SCREEN_W/2.0;
            temy*=SCREEN_H/2.0;temy+=SCREEN_H/2.0;
            scx=temx,scy=temy;scz=1/temz;
        }    
    }
    void ScreenToCamara(Camara camara){
        float temx=scx,temy=scy,temz=1/scz;
        temx-=SCREEN_W/2.0;temx/=SCREEN_W/2.0;
        temy-=SCREEN_H/2.0;temy/=SCREEN_H/2.0;
        temx*=camara.r;temx/=camara.d/temz;
        temy*=camara.t;temy/=camara.d/temz;
        csx=temx,csy=temy,csz=temz;
    }
    bool ifInScreenSpace(Camara camara){
        if(csz>=camara.n&&csz<=camara.f
            &&!(scx<=0||scx>=SCREEN_W||scy<=0||scy>=SCREEN_H)
        ){inSc=true;}else{inSc=false;}
        return inSc;
    }
};
